<!-- 适用于table组件的数据获取配置 -->
<template>
  <a-form
    :form="form"
    :label-col="{ span: labelCol }"
    :wrapper-col="{ span: wrapperCol }"
  >
    <div class="panel">
      <div class="panel-title">
        表格配置
      </div>
      <a-form-item label="数据集" class="dataset-div">
        <span v-if="widgetType !== widgetTypeEnum.system" class="ant-form-text">
          {{ datasetName }}
        </span>
        <a-select
          v-else
          v-decorator="['dataId']"
          size="small"
          placeholder="请选择"
          @change="(value) => handleDatasetChange(value)"
        >
          <a-select-option v-for="item in datasetList.dataset" :key="+item.id">
            {{ item.name }}
          </a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item label="标题内容">
        <a-input
          v-decorator="['title']"
          size="small"
          @change="onHandleTitleChange"
        />
      </a-form-item>
      <a-row v-show="tableColumnsOptions.length > 0" style="margin-top: 8px;">
        <a-col :span="labelCol" style="color: rgba(0, 0, 0, 0.85);"
          >展示字段</a-col
        >
        <a-col :span="wrapperCol">
          <column-selector
            :options="tableColumnsOptions"
            :value="formData.columns || tableColumnsOptions.map((c) => c.value)"
            @change="handleColumnSelectChange"
            @optiondragend="handleColumnSort"
          />
        </a-col>
      </a-row>
    </div>
  </a-form>
</template>

<script lang="ts">
import { Vue, Prop, Component, Watch } from 'vue-property-decorator'
import {
  IDatasetList,
  IColumn,
  IKeyValue,
} from '@/components/common/VisualizationDashboard/interface'
import { widgetTypeEnum } from '@/components/common/VisualizationDashboard/util'
import ColumnSelector from '@/components/form/column-selector.vue'
import { isEqual, debounce } from 'lodash'

@Component({
  components: {
    ColumnSelector,
  },
})
export default class TableFetchForm extends Vue {
  @Prop() chartType!: string
  @Prop({ default: '' }) widgetType!: 'system' | 'dataset' | 'pipeline' // system-系统组件 pipeline - pipeline组件
  @Prop({ default: () => [] }) datasetList!: IDatasetList // 数据集列表
  @Prop({ default: () => ({}) }) formData!: IKeyValue
  @Prop({ default: () => [] }) tableColumns!: IColumn[]
  @Prop({
    type: Number,
    required: false,
    default() {
      return 8
    },
  })
  labelCol!: number

  @Prop({
    type: Number,
    required: false,
    default() {
      return 16
    },
  })
  wrapperCol!: number

  private form: any
  private widgetTypeEnum = widgetTypeEnum // widget 类型：系统组件、pipeline组件，目前只有系统组件会传该字段

  private tableJson = {
    curPage: 1,
    pageSize: 50,
    name: '_record_id_',
    filters: [],
    sortCol: [],
  }

  beforeCreate() {
    this.form = this.$form.createForm(this, {
      name: 'tableFetchForm',
    })
  }

  @Watch('formData', { immediate: true, deep: true })
  onFormDataChange(newValue: IKeyValue, oldValue: IKeyValue) {
    if (isEqual(newValue, oldValue)) {
      return
    }
    if (newValue.dataId || newValue.title) {
      this.setFormData()
      if (newValue.dataId && +newValue.dataId !== +oldValue?.dataId) {
        // dataId change， fetch table columns
        this.handleDatasetChange(
          this.formData.dataId,
          oldValue?.dataId ? undefined : this.formData.columns,
          {
            ...this.tableJson,
            sortCol: newValue.sortCol || [],
          }
        )
      }
    }
  }

  /**
   * 勾选列的选项
   */
  private get tableColumnsOptions() {
    return this.tableColumns.map((column: IColumn) => ({
      value: column.name,
      text: column.name,
      label: column.name,
    }))
  }

  /**
   * 数据集名称
   */
  private get datasetName() {
    if (this.widgetType !== widgetTypeEnum.system) {
      const type = this.formData.dataType === 'dataset' ? 'dataset' : 'pipeline'
      const target =
        this.datasetList[type].filter(
          (list: any) => list.id === this.formData.dataId
        )[0] || {}
      return target.name || ''
    }
    return ''
  }

  /**
   * 设置数据
   */
  private setFormData() {
    this.$nextTick(() => {
      if (this.widgetType === widgetTypeEnum.system) {
        this.form.setFieldsValue({
          dataId: this.formData.dataId,
          title: this.formData.title,
        })
      } else {
        this.form.setFieldsValue({
          title: this.formData.title,
        })
      }
    })
  }

  /**
   * 获取数据集的列
   * @param columns string[] 当前选择的列value
   */
  private handleDatasetChange(
    value: string,
    columns?: string[],
    tableJson?: any
  ) {
    if (!value) {
      return
    }
    const extraData: any = {}
    if (columns) {
      extraData.columns = columns
    }
    const parameters: any = {
      id: +value,
      type: this.formData.dataType,
    }
    if (tableJson) {
      parameters.tableJson = tableJson
    }

    this.$emit('change', parameters, extraData)
  }

  private handleColumnSelectChange(value: string[]) {
    const { dataId, dataType } = this.formData
    this.$emit(
      'change',
      {
        id: dataId,
        type: dataType,
      },
      {
        columns: value,
      }
    )
  }

  //  去抖处理 频繁输入文本
  private onHandleTitleChange = debounce(
    (event: any) => this.handleTitleChange(event),
    300
  )
  /**
   * 标题变化
   */
  private handleTitleChange(event: any) {
    const newValue = event.target.value.trim()
    const { dataId, dataType } = this.formData
    this.$emit(
      'change',
      {
        id: dataId,
        type: dataType,
      },
      {
        title: newValue,
      }
    )
  }

  private handleColumnSort(value: IKeyValue[]) {
    const sortedValue = value.filter((v) =>
      this.formData.columns.includes(v.value)
    )
    this.handleColumnSelectChange(sortedValue.map((v) => v.value))
  }
}
</script>

<style lang="less" scoped>
/deep/ .dataset-div {
  .ant-select-disabled {
    color: rgba(0, 0, 0, 0.65);

    .ant-select-selection {
      background-color: #fff;
      border-width: 0;
      cursor: default;

      .ant-select-arrow {
        visibility: hidden;
      }
    }
  }
}

/deep/ .ant-form-item-label > label::after {
  content: '';
}
</style>
